package com.rfid.sockethelper;

import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.rfid.DirectoryBean;
import com.rfid.config.ConstantsConfig;
import com.rfid.util.FileUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public abstract class SocketBase extends Base{
    protected static final int SERVER_PORT = 65432;
    // 品牌-型号
    protected static final String PHONE_INFO = Build.BRAND + " - " + Build.MODEL;
    public Executor mExecutor;

    public interface OnReceiveListener {
        void onReceived(String ip,short cmd,CharSequence ...text);
        void onConnect(String ip,boolean connect);
    }

    protected OnReceiveListener onReceiveListener;

    public SocketBase(OnReceiveListener onReceiveListener) {
        this.onReceiveListener = onReceiveListener;
        mExecutor = Executors.newCachedThreadPool();
    }

    public void setReceiveListener(OnReceiveListener listener) {
        onReceiveListener = listener;
    }

    protected void postConnectStatus(String ip,boolean connect) {
        System.out.println("postConnectStatus connect = " + connect);
        if (handler == null) {
            System.out.println("postConnectStatus handler is null");
            return;
        }
        Message message = Message.obtain(handler);
        Bundle bundle = new Bundle();
        bundle.putString("ip",ip);
        bundle.putBoolean("connect",connect);
        message.setData(bundle);
        message.what = 2;
        message.sendToTarget();
    }

    protected void postToUI(String ip,short cmd,String ...text) {
        if (handler == null) {
            return;
        }
        Message message = Message.obtain(handler);
        message.what = 1;
        Bundle bundle = new Bundle();
        bundle.putString("ip",ip);
        bundle.putCharSequenceArray("text",text);
        bundle.putShort("cmd",cmd);
        message.setData(bundle);
        message.sendToTarget();
    }

    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            int what = msg.what;
            System.out.println("recever handler = " + what);
            if (onReceiveListener == null) {
                System.out.println("onReceiveListener == null");
                return;
            }
            if (what == 1) {
                Bundle bundle = msg.getData();
                String ip = bundle.getString("ip");
                CharSequence text[] = bundle.getCharSequenceArray("text");
                short cmd = bundle.getShort("cmd");
                onReceiveListener.onReceived(ip,cmd, text);
            } else if (what == 2) {
                Bundle bundle = msg.getData();
                onReceiveListener.onConnect(bundle.getString("ip"),bundle.getBoolean("connect"));
            } else if (what == 3) {
                Bundle bundle = msg.getData();
//                onReceiveListener.onConfig(bundle.getString("ip"),bundle.getString("name"),bundle.getString("config"));
            }
        }
    };

    public void clear() {
        System.out.println("clear");
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        }
        onReceiveListener = null;
    }

    protected String receive(InputStream inputStream,String ip,short cmd) throws Exception {
//        System.out.println("receive cmd = " + cmd);
        String text = null;
        if (cmd == IOHelper.CMD_STR) {
            text = IOHelper.readString(inputStream);
        } else if (cmd == IOHelper.CMD_SET_CONFIG) {
            String name = IOHelper.readString(inputStream);
            String config = IOHelper.readString(inputStream);
            String data[] = new String[]{name, config};
            postToUI(ip,cmd,data);
        } else if (cmd == IOHelper.CMD_HEART) {
            System.out.println("CMD_HEART");
        } else if (cmd == IOHelper.CMD_RESPON_CONFIGS) {
            text = IOHelper.readConfigNames(inputStream);
        } else if (cmd == IOHelper.CMD_PULL_CONFIG) {
            text = IOHelper.readString(inputStream);
        } else if (cmd == IOHelper.CMD_QUERY_CONFIGS) {
            text = "READCONFIGS";
        } else if (cmd == IOHelper.CMD_SEND_FILE) {
            text = IOHelper.readFile(inputStream, ConstantsConfig.directoryPath);
        } else if (cmd == IOHelper.CMD_REQ_FILE_LIST) {
            text = IOHelper.readQueryFileList(inputStream);
            File dir = new File(text);
            if (dir.isDirectory()) {
                DirectoryBean bean = new DirectoryBean();
                bean.setPath(text);
                List<DirectoryBean.FileEntity> entities = new ArrayList<>();
                bean.setChildren(entities);
                File children[] = dir.listFiles();
                if (children != null) {
                    for (File file : children) {
                        DirectoryBean.FileEntity entity = new DirectoryBean.FileEntity();
                        entity.setPath(file.getPath());
                        entity.setLength(file.length());
                        entity.setFile(file.isFile());
                        entities.add(entity);
                    }
                }
                sendFileListInfo(ip,bean);
            } else {
                System.out.println(text + " is not a directory");
            }
        } else if (cmd == IOHelper.CMD_REQ_FILE) {
            text = IOHelper.readString(inputStream);
            String path = text;
            sendFile(ip,path);
        } else if (cmd == IOHelper.CMD_SEND_FILE_LIST) {
            text = IOHelper.readFileList(inputStream);
        } else if (cmd == IOHelper.CMD_SET_FILE) {
            text = IOHelper.readSetFile(inputStream);
        } else if (cmd == IOHelper.CMD_DELETE_FILE) {
            text = IOHelper.readDeleteFile(inputStream);
            FileUtil.rm(text);
        }
        return text;
    }

    protected abstract void sendFileListInfo(String ip,DirectoryBean bean);
    protected abstract void sendFile(String ip,String path);

}
